package GUILayer;

import java.awt.*;
import java.awt.event.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.table.*;

import CtrLayer.CustomerCtr;
import CtrLayer.ProductCtr;
import CtrLayer.OrderCtr;
import ModelLayer.Cash;
import ModelLayer.Customer;
import ModelLayer.LineItem;
import ModelLayer.Order;

public class OrdersAndLeasingGUI {
	
	private static int idO = 1000;
	private static OrderCtr orderCtr = new OrderCtr();
	private static CustomerCtr customerCtr = new CustomerCtr();
	private static ProductCtr productCtr = new ProductCtr();
    private JPanel panel;
    private JTable ordersTable;
    private Object[][] data;	// table data
    private int size; 			// table no. of rows
    private final DateFormat toFormat = new SimpleDateFormat("dd/MM/yyyy");
    
	public OrdersAndLeasingGUI()
	{
		
	}
	
	
	
	private JPanel makeSearchPanel()
	{
		JPanel panel = new JPanel();
		int sp=8;
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "Search"),BorderFactory.createEmptyBorder(sp, sp, sp, sp)));
		
		JLabel idORname = new JLabel("ID");
		final JTextField field = new JTextField(10);
		JButton but1 = new JButton("Search");
		
		but1.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent ev) {
				
				try{
					String searchBY = field.getText();
					
					int rowHigh = -1;
					for(int i=0;i<size;i++)
						if( data[i][0].toString().equals(searchBY)) {rowHigh = i;break;}
					
					if(rowHigh>=0) 
					{
						ordersTable.setRowSelectionInterval(rowHigh, rowHigh);
						ordersTable.scrollRectToVisible(ordersTable.getCellRect(rowHigh,0, true)); 
					}
				}
				catch(Exception ex){}
				
			}
			
		});
		
		panel.add(idORname);
		panel.add(field);
		panel.add(but1);
		
		return panel;
	}
	
	
	
	
	private JPanel makeAddOrderPanel()
	{
		JPanel panel = new JPanel();
		int sp=8;
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "Add New Order"),BorderFactory.createEmptyBorder(sp, sp, sp, sp)));
		
		JLabel custIDorName = new JLabel("Customer ID or Name");
		final JTextField field = new JTextField(10);
		JButton but1 = new JButton("Add");
		
		but1.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent ev) {
				
				try{
					String custIDorName = field.getText();
					if(custIDorName.isEmpty()) custIDorName="0";
					
					Customer customer = customerCtr.getCustomer(custIDorName);
					
					if(orderCtr.createOrder(idO, customer.getId(), Main.logUS))
					{
						orderFrame(idO);
						idO++;
					}
					
					reAddGrid();
				}
				catch(Exception ex){}
				
			}
			
		});
		
		panel.add(custIDorName);
		panel.add(field);
		panel.add(but1);
		
		return panel;
	}
	

	
	
	private JPanel makeGridListOrders()
	{
		Iterator<?> it = orderCtr.getOrdersIterator();
		size = orderCtr.getOrdersSize();
        
		String[] columnNames = {"Id","Total","Customer","Employee","Date","State"};
		data = new Object[size][columnNames.length];
		
		int i=0;
		while(it.hasNext())
		{
			Order order = (Order)it.next();
			data[i][0]= order.getId();
			data[i][1]= order.getTotal();
			data[i][2]= order.getCustomerName();
			data[i][3]= order.getEmployee().getName();
			data[i][4]= toFormat.format(order.getStartDate());
			data[i][5]= order.getState();
			i++;
		}
		
		JPanel gridOrders = new JPanel();
		DefaultTableModel dtm = new DefaultTableModel(data,columnNames){
			private static final long serialVersionUID = 1L;

			public boolean isCellEditable(int row, int col){		// <-- override for non-editable cells
				return false;
			}
		};
		

		
		
		ordersTable = new JTable(dtm);
		ordersTable.getTableHeader().addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				int col = ordersTable.columnAtPoint(e.getPoint());
				if(col==8)
				{
					int selected = getSelectedOrders(ordersTable);
					if(selected==0)
					{
						JOptionPane.showConfirmDialog(null, "You didn't selected any orders","Info",JOptionPane.CLOSED_OPTION);
					}
					else
					{
						int answer = JOptionPane.showConfirmDialog(null, "Do you want to change the state to 'close' for "+ selected +" order(s) ?","Confirm change state",JOptionPane.YES_NO_OPTION);
						if(answer == JOptionPane.YES_OPTION)
						{
							changeStateSelectedProducts(ordersTable);
						}
					}
				}
			}
		});
		
		
		
		TableColumnModel tcm = ordersTable.getColumnModel();
		tcm.getColumn(0).setPreferredWidth(40);  
		tcm.getColumn(2).setPreferredWidth(40);
		tcm.getColumn(3).setPreferredWidth(63);
		
		JScrollPane ordersTableScroll = new JScrollPane(ordersTable);
		ordersTableScroll.setPreferredSize(new Dimension(600,200));
		ordersTableScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		ordersTableScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		
		gridOrders.add(ordersTableScroll,BorderLayout.CENTER);
		
		
		
		ordersTable.addMouseListener(new MouseAdapter(){
			
			public void mouseClicked(MouseEvent e)
			{
				if(e.getClickCount()==2)
				{
					JTable target = (JTable)e.getSource();
					int row = target.getSelectedRow();
					int idOrder = 0;
					try{ 
						idOrder = (Integer)target.getModel().getValueAt(row, 0);
						orderFrame(idOrder);
					}
					catch(Exception ex){}
				}
			}
			
		});
		
		return gridOrders;
	}
	
	
	
	
	
	private void orderFrame(final int idO)
	{
		final JFrame frame = new JFrame("Order id "+idO);
		JPanel mainPanel = new JPanel();
		
		try{
			final Order order = orderCtr.getOrder(idO);
			order.updateTotal();
			Iterator<?> itProds = order.getProducts();
			
			JLabel lab1 = new JLabel("Id");
			JLabel lab2 = new JLabel("Employee order");
			JLabel lab3 = new JLabel("Employee payment");
			JLabel lab4 = new JLabel("Customer");
			JLabel state = new JLabel("State");
			
			
			JLabel llab1 = new JLabel();
			JLabel llab2 = new JLabel();
			JLabel llab3 = new JLabel();
			JLabel llab4 = new JLabel();
			
			final String[] listS = {"Pending","Closed"};
			final JComboBox stateBox = new JComboBox(listS);
			
			int indexSelected = 0;
			for(int i=1;i<listS.length;i++)
				if(listS[i].equals(order.getState())) {indexSelected = i;break;}
			
			stateBox.setSelectedIndex(indexSelected);
			stateBox.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent e) {
					order.setState(listS[stateBox.getSelectedIndex()]);
				}
			});
			
			llab1.setText(String.valueOf(order.getId()));
			llab2.setText(order.getEmployee().getName());
			llab3.setText(order.getPaymentStaffName());
			llab4.setText(order.getCustomerName());
			
			
			
			/*  START BILL */
			JPanel logo = new JPanel(new GridLayout(1,1));
			JLabel logoJ = new JLabel("Vestbjerg byggecentre");
			logoJ.setFont(new Font("Serif",Font.BOLD,18));
			logoJ.setHorizontalAlignment(JLabel.CENTER);
			logo.add(logoJ);
			
			
			JPanel address = new JPanel(new GridLayout(1,1));
			JLabel addressJ = new JLabel("<html>Vestbjerg byggecentre A/S<br>AALBORG,SOFIENDALSVEJ 60<br>POST CODE:9000</html>");
			addressJ.setHorizontalAlignment(JLabel.CENTER);
			addressJ.setFont(new Font("SansSerif",Font.ITALIC,9));
			address.add(addressJ);
			
			
			GridLayout layO = new GridLayout(0,2);
			layO.setHgap(20);
			
			JPanel prods = new JPanel(); // products
			prods.setLayout(new BoxLayout(prods,BoxLayout.Y_AXIS));
			
			while(itProds.hasNext())
            {
				JPanel pan = new JPanel();
				pan.setLayout(layO);
				
                LineItem li = (LineItem)itProds.next();
                
                JLabel quantity = new JLabel(String.valueOf(li.getQuantity())+" x");
                JLabel price = new JLabel(String.format("%.2f",li.getProduct().getFinalPrice()));
                JLabel productName = new JLabel(li.getProduct().getName());
                JLabel finalPrice = new JLabel(String.format("%.2f",li.getSubtotal()));
                
                quantity.setFont(new Font("Serif",Font.ITALIC,13));
                price.setFont(new Font("Serif",Font.ITALIC,13));
                productName.setFont(new Font("Serif",Font.ITALIC,13));
                
                price.setHorizontalAlignment(JLabel.RIGHT);
                productName.setHorizontalAlignment(JLabel.RIGHT);
                
                pan.add(quantity);
                pan.add(price);
                
                pan.add(productName);
                pan.add(finalPrice);
                
                prods.add(pan);
            }
			
			
		
			JLabel subTotal = new JLabel("SUBTOTAL");
			JLabel subTotalV = new JLabel(String.format("%.2f",order.getTotal()));
			
			JLabel subTotal2 = new JLabel("SUBTOTAL");
			JLabel subTotalV2 = new JLabel(String.format("%.2f",order.getTotal()+order.getTotal()*0.25));
			
			JLabel discount = new JLabel("DISCOUNT");
			JLabel discountV = new JLabel(String.format("%.2f",order.getDiscount()));
			
			JLabel vat = new JLabel("VAT");
			JLabel vatV = new JLabel("25%");
			
			JLabel total = new JLabel("TOTAL");
			JLabel totalV = new JLabel(String.format("%.2f",order.getFinalTotal()));
			
			JLabel moneyReceive = new JLabel("Cash");
			JLabel moneyReceiveV = new JLabel(String.format("%.2f",order.getPaidAmount()));
			
			JLabel change = new JLabel("Change");
			JLabel changeV = new JLabel(String.format("%.2f",order.getPaidAmount()-order.getFinalTotal()));
			
			JLabel sDate = new JLabel("Start date");
			JLabel sDateV = new JLabel(toFormat.format(order.getStartDate()).toString());
			
			JLabel eDate = new JLabel("End date");
			JLabel eDateV = new JLabel(toFormat.format(order.getEndDate()).toString());
			
			
			subTotalV.setHorizontalAlignment(JLabel.RIGHT);
			subTotalV2.setHorizontalAlignment(JLabel.RIGHT);
			discountV.setHorizontalAlignment(JLabel.RIGHT);
			totalV.setHorizontalAlignment(JLabel.RIGHT);
			moneyReceiveV.setHorizontalAlignment(JLabel.RIGHT);
			changeV.setHorizontalAlignment(JLabel.RIGHT);
			vatV.setHorizontalAlignment(JLabel.RIGHT);
			sDateV.setHorizontalAlignment(JLabel.RIGHT);
			eDateV.setHorizontalAlignment(JLabel.RIGHT);
			
			JPanel prices = new JPanel();
			prices.setLayout(layO);
			
			
			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(subTotal); 
			prices.add(subTotalV);

			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			
			prices.add(vat); 
			prices.add(vatV);
			
			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(subTotal2); 
			prices.add(subTotalV2);

			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(discount); 
			prices.add(discountV);
			
			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(total); 
			prices.add(totalV);
			
			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(moneyReceive);
			prices.add(moneyReceiveV);
			
			prices.add(change);
			prices.add(changeV);
			
			prices.add(new JLabel(""));
			prices.add(new JLabel(""));
			
			prices.add(sDate);
			prices.add(sDateV);
			
			prices.add(eDate);
			prices.add(eDateV);
			
			changeFont(prices, new Font("Serif",Font.PLAIN,12));
			
			prices.setAlignmentY(Component.CENTER_ALIGNMENT);
			prods.setAlignmentY(Component.CENTER_ALIGNMENT);
			
			JPanel pricess = new JPanel();
			pricess.add(prices);
			
			JPanel prodss = new JPanel();
			prodss.add(prods);
			
			JPanel bill = new JPanel();
			bill.setSize(new Dimension(500,300));
			bill.setLayout(new BoxLayout(bill, BoxLayout.Y_AXIS));
			bill.add(logo);
			bill.add(address);
			bill.add(prodss);
			bill.add(pricess);
			
			final JScrollPane billScroll = new JScrollPane(bill);
			billScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
			billScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
			billScroll.setPreferredSize(new Dimension(200,300));
			
			/*  END BILL */
			
			
			JPanel grid1 = new JPanel();
			JPanel grid3 = new JPanel();
			
			GridLayout gridLay = new GridLayout(0,2);
			gridLay.setHgap(20);
			
			int sp=10;
			grid1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED),BorderFactory.createEmptyBorder(sp, sp, sp, sp)));
			
			grid1.setLayout(gridLay);
			grid3.setLayout(new FlowLayout());
			
			grid1.add(lab1);
			grid1.add(llab1);
			
			grid1.add(lab2);
			grid1.add(llab2);
			
			grid1.add(lab3);
			grid1.add(llab3);
			
			grid1.add(lab4);
			grid1.add(llab4);
			
			grid1.add(state);
			grid1.add(stateBox);
			
			grid3.add(grid1);
			grid3.add(billScroll);
			
			
			JPanel buttons = new JPanel(new GridLayout(0,3));
			final JButton close = new JButton("Save & Close");
			JButton printBill = new JButton("Print bill");
			JButton addProduct = new JButton("Add product");
			JButton payButton = new JButton("Payment");
			JButton addPickupDisc = new JButton("Add Pickup Discount");
			JButton addBulk = new JButton("Add Bulk Discount");
			
			buttons.add(addProduct);
			buttons.add(addPickupDisc);
			buttons.add(addBulk);
			buttons.add(payButton);
			buttons.add(printBill);
			buttons.add(close);
			
			
			addPickupDisc.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent e) {
					order.setPickupDiscount();
					close.doClick();
					orderFrame(order.getId());
				}
			});
			
			
			addBulk.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent arg0) {
					String discountBulkString = JOptionPane.showInputDialog(null, "Insert discount:", "Bulk Discount",JOptionPane.OK_OPTION);
					try{
						double discountBulk = Double.valueOf(discountBulkString);
						
						order.setQuantityDiscount(discountBulk);
						close.doClick();
						orderFrame(order.getId());
					}
					catch(Exception ex) {}
				}
				
			});
			
			
			
			payButton.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent arg0) {
					String amountPayedString = JOptionPane.showInputDialog(null, "Insert amount:", "Payment: cash or credit card",JOptionPane.OK_OPTION);
					try{
						double amountPayed = Double.valueOf(amountPayedString);
						
						order.addPayment(new Cash(order.getId(),amountPayed));
						close.doClick();
						orderFrame(order.getId());
					}
					catch(Exception ex) {}
				}
				
			});
			
			
			
			
			addProduct.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent ex1) {
					try{
						JTextField productId = new JTextField(5);
						JTextField quantity = new JTextField(5);
						
						JPanel pANDq = new JPanel();
						pANDq.add(new JLabel("Product id:"));
						pANDq.add(productId);
						pANDq.add(Box.createHorizontalStrut(15));
						pANDq.add(new JLabel("Quantity:"));
						pANDq.add(quantity);
						
						int answear = JOptionPane.showConfirmDialog(null,pANDq, "Add Product", JOptionPane.OK_CANCEL_OPTION);
						if(answear == JOptionPane.OK_OPTION)
						{
							int idP = Integer.parseInt(productId.getText());
							int quant = Integer.parseInt(quantity.getText());
							
							String messageProductExistNoStock = "The product with id "+idP+" does not have such stock available.";
							String messageProductDoesNotExist = "The product with id "+idP+" does not exist.";
							String messageProductStockSmall = "Stock of product "+idP+" is below 20 items";
							
							int ans = orderCtr.addProduct(idO, idP, quant);
							
							if(ans >= 1)
							{
								close.doClick();
								orderFrame(idO);
								if(ans == 2)
									JOptionPane.showConfirmDialog(null,messageProductStockSmall,"Stock limit",JOptionPane.CLOSED_OPTION,JOptionPane.CANCEL_OPTION);
								
							}
							else if(ans == 0) JOptionPane.showConfirmDialog(null,messageProductExistNoStock,"Error product",JOptionPane.CLOSED_OPTION,JOptionPane.CANCEL_OPTION);
							else JOptionPane.showConfirmDialog(null,messageProductDoesNotExist,"Error product",JOptionPane.CLOSED_OPTION,JOptionPane.CANCEL_OPTION);
						}
					}
					catch(Exception ex){}
				}
			});
			
			close.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent ev) {
					frame.setVisible(false);
					reAddGrid();
				}
			});
			
			
			printBill.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent ev) {	
					printJavaComponent("Print Bill:",billScroll);
				}
			});
			
			
			mainPanel.add(grid3);
			mainPanel.add(buttons);
			
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		frame.setContentPane(mainPanel);
		frame.setSize(new Dimension(500,410));
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		frame.setVisible(true);
		frame.setLocationRelativeTo(null);
	}
	
	
	
	
	
	public void printJavaComponent(String title,final JComponent componentJava) 
	{
	    PrinterJob job = PrinterJob.getPrinterJob();
	    job.setJobName(title);
	 
	    job.setPrintable (new Printable() {   
	    	
	        public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
	            if (pageIndex > 0) {
	                return(Printable.NO_SUCH_PAGE);
	            } else {
	                Graphics2D g2d = (Graphics2D)g;
	                g2d.translate(pageFormat.getImageableX(),
	                pageFormat.getImageableY());
	 
	                componentJava.paint(g2d);
	 
	                return(Printable.PAGE_EXISTS);
	            }
	        }
	    });
	         
	    if (job.printDialog()) {
	        try {
	            job.print();
	        } catch (PrinterException e) {
	            System.err.println(e.getMessage());
	        }
	    }
	}

	
	
	
	private static void changeFont(Component component, Font font)
	{
		component.setFont(font);
		if(component instanceof Container)
		{
			for(Component child : ( (Container)component).getComponents())
			{
				changeFont(child,font);
			}
		}
	}
	
	
	private void popupError(String message)
	{
		JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.INFORMATION_MESSAGE);
	}
	
	
	private void reAddGrid()
	{
		panel.remove(1);
		panel.add(makeGridListOrders());
		panel.revalidate();
	}
	
	
	public JPanel makeProductsTab()
	{
		panel = new JPanel();
		
		JPanel firstPanel = new JPanel();
		firstPanel.add(makeSearchPanel());
		firstPanel.add(makeAddOrderPanel());
		
		panel.add(firstPanel);
		panel.add(makeGridListOrders());
		
		return panel;
	}

	
	
	
	
	private int getSelectedOrders(JTable table)
	{
		int count=0;
		for(int i=0;i<table.getRowCount();i++)
		{
			if( (Boolean)table.getValueAt(i, 6) == true ) count++;
		}
		return count;
	}
	
	private void changeStateSelectedProducts(JTable table)
	{
		for(int i=0;i<table.getRowCount();i++)
		{
			if( (Boolean)table.getValueAt(i, 6) == true )
			{
				int orderID = (Integer)table.getValueAt(i, 0);
				orderCtr.changeState(orderID, "closed");
			}
		}
		reAddGrid();
	}
}
